package cn.kivensoft.util.impl;

import cn.kivensoft.util.Crypt;
import cn.kivensoft.util.Fmt;
import cn.kivensoft.util.Strings;

import java.security.MessageDigest;

public class KivenCrypt extends BaseCrypt implements Crypt {
	private static final int DEFAULT_SALT_LEN = 6;
	private static final String MAGIC = "$74$";


	@Override
	public String encrypt(String passwd) {
		String salt = encodeBase64(gensalt(DEFAULT_SALT_LEN));
		try {
			return doencrypt(passwd, salt);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean verify(String passwd, String encrypt) {
		if (encrypt == null
				|| encrypt.length() < MAGIC.length() + 8 + 1 + 22
				|| !MAGIC.equals(encrypt.substring(0, MAGIC.length()))
				|| encrypt.charAt(MAGIC.length() + 8) != '$')
			return false;

		try {
			String enc = doencrypt(passwd, encrypt.substring(MAGIC.length(), MAGIC.length() + 8));
			return encrypt.equals(enc);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private String doencrypt(String passwd, String salt) throws Exception {
		MessageDigest ctx = MessageDigest.getInstance("md5");
		ctx.update(Strings.toBytes(MAGIC));
		ctx.update(Strings.toBytes(salt));
		ctx.update(Strings.toBytes(passwd));

		byte[] finalState = ctx.digest();

		return Fmt.concat(MAGIC, salt, "$", encodeBase64(finalState));
	}

}
